package com.huashi.dealer.modular.business.balance.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huashi.dealer.commonEntity.*;
import com.huashi.dealer.core.exception.CommonException;
import com.huashi.dealer.core.exception.ServiceException;
import com.huashi.dealer.core.util.BizAssertUtil;
import com.huashi.dealer.core.util.SaTokenUtil;
import com.huashi.dealer.core.util.TimeUtil;
import com.huashi.dealer.modular.business.balance.bo.BalanceBo;
import com.huashi.dealer.modular.business.balance.mapper.BalanceApplyMapper;
import com.huashi.dealer.modular.business.balance.mapper.BalanceMapper;
import com.huashi.dealer.modular.business.balance.param.*;
import com.huashi.dealer.modular.business.user.mapper.StoreUserMapper;
import com.huashi.dealer.modular.business.user.mapper.UserMapper;
import com.huashi.dealer.modular.business.user.mapper.UserRebateLogMapper;
import com.huashi.dealer.modular.business.user.mapper.UserWriteoffLogMapper;
import com.huashi.dealer.modular.business.balance.service.BalanceService;
import com.huashi.dealer.modular.business.balance.vo.BalanceVo;
import com.huashi.dealer.modular.business.balance.vo.BalanceApplyListVo;
import com.huashi.dealer.modular.business.balance.vo.RechargeReviewListVo;
import com.huashi.dealer.modular.business.user.service.StoreUserManageService;
import com.huashi.dealer.modular.business.user.service.UserService;
import com.huashi.dealer.modular.business.balance.mapper.UserRechargeReviewMapper;
import jakarta.annotation.Resource;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.alibaba.fastjson.JSON;

/**
 * API打款单Service实现类
 *
 * @author 谭陈强
 * @since 2025-07-30
 */
@Service("apiBalanceServiceImpl")
@Validated
public class BalanceServiceImpl extends ServiceImpl<BalanceMapper, UserBalanceLog> implements BalanceService {

    @Resource
    private BalanceMapper balanceMapper;

    @Resource
    private BalanceApplyMapper balanceApplyMapper;

    @Resource
    private UserService userService;
    
    @Resource
    private UserRebateLogMapper userRebateLogMapper;
    
    @Resource
    private UserWriteoffLogMapper userWriteoffLogMapper;

    @Resource
    private UserRechargeReviewMapper userRechargeReviewMapper;
    @Resource
    private StoreUserMapper storeUserMapper;

    @Resource
    private UserMapper userMapper;
    @Override
    public void applyBalance(String money, String images) {
        UserBalanceApply userBalanceApply = new UserBalanceApply();
        try {
            if (money == null || money.isEmpty()) {
                throw new ServiceException("申请金额不能为空");
            }
            if (images == null || StrUtil.isEmpty(images)){
                throw new ServiceException("请上传图片");
            }
            // 申请打款单
            // 这里需要实现打款单申请逻辑，包括：
            // 1. 验证用户余额
            Long userId = SaTokenUtil.getLoginId();
            User user = userService.getById(userId);
            userBalanceApply.setBeforeBalance(user.getBalance());
            userBalanceApply.setBeforeRebate(user.getRebate());
            userBalanceApply.setBeforeWriteoff(user.getWriteoff());
            userBalanceApply.setMoney(new BigDecimal(money));
            userBalanceApply.setUserId(user.getUserId());
            userBalanceApply.setBalanceTime(System.currentTimeMillis()/1000);
            userBalanceApply.setCreateTime(System.currentTimeMillis()/1000);
            userBalanceApply.setImages(images);
            // 2. 保存申请记录到数据库
            balanceApplyMapper.insert(userBalanceApply);

        } catch (Exception e) {
            throw new CommonException("申请打款单失败：" + e.getMessage());
        }
    }

    @Override
    public Page<UserBalanceLog> getBalanceLogList(Page<UserBalanceLog> page, Integer time) {
        try {
            // 获取当前登录用户ID
            Long userId = SaTokenUtil.getLoginId();

            // 调用mapper获取余额日志列表
            Page<UserBalanceLog> balanceLogPage = balanceMapper.getBalanceLogList(userId, page,time);
            return balanceLogPage;
//            Page<UserBalanceLog> balanceLogPage=this.page(PageFactory.defaultPage(),new LambdaQueryWrapper<UserBalanceLog>().eq(UserBalanceLog::getUserId, userId));
//            return balanceLogPage;
        } catch (Exception e) {
            throw new CommonException("获取余额日志列表失败：" + e.getMessage());
        }
    }

    @Override
    public BalanceResponseParam getBalanceDetail(String token) {
        BalanceResponseParam responseParam = new BalanceResponseParam();
        
        try {
            if (token == null || token.isEmpty()) {
                throw new CommonException("用户令牌不能为空");
            }
            
            // TODO: 获取余额详情
            // 这里需要注入UserMapper并查询数据库
            
            // 模拟余额详情
            responseParam.setBalance(new BigDecimal("1000.00"));
            responseParam.setBalanceAll(new BigDecimal("1000.00"));
            responseParam.setPoints(100);
            responseParam.setPayMoney(new BigDecimal("654.00"));
            responseParam.setExpendMoney(new BigDecimal("0.00"));
            responseParam.setSalesMoney(new BigDecimal("10000.00"));
            responseParam.setGradeId(1L);
            responseParam.setGradeName("普通会员");
            
        } catch (Exception e) {
            throw new CommonException("获取余额详情失败：" + e.getMessage());
        }
        
        return responseParam;
    }

    @Override
    public void withdrawBalance(BalanceRequestParam requestParam) {
        try {
            if (requestParam.getToken() == null || requestParam.getToken().isEmpty()) {
                throw new CommonException("用户令牌不能为空");
            }
            if (requestParam.getWithdrawMoney() == null || requestParam.getWithdrawMoney().compareTo(BigDecimal.ZERO) <= 0) {
                throw new CommonException("提现金额不能为空或小于等于0");
            }
            if (requestParam.getBankName() == null || requestParam.getBankName().isEmpty()) {
                throw new CommonException("银行名称不能为空");
            }
            if (requestParam.getBankAccount() == null || requestParam.getBankAccount().isEmpty()) {
                throw new CommonException("银行账号不能为空");
            }
            if (requestParam.getAccountName() == null || requestParam.getAccountName().isEmpty()) {
                throw new CommonException("开户名不能为空");
            }

            // TODO: 提现申请
            // 这里需要实现提现申请逻辑

            // 模拟提现申请
            System.out.println("提现申请：" + requestParam.getWithdrawMoney());

        } catch (Exception e) {
            throw new CommonException("提现申请失败：" + e.getMessage());
        }
    }

    @Override
    public BalanceResponseParam getBalanceApplyList(String token, Integer page, Integer listRows) {
        BalanceResponseParam responseParam = new BalanceResponseParam();
        
        try {
            if (token == null || token.isEmpty()) {
                throw new CommonException("用户令牌不能为空");
            }
            
            // TODO: 获取打款单列表
            // 这里需要注入BalanceApplyMapper并查询数据库
            
            // 模拟打款单列表
            List<BalanceResponseParam.BalanceApplyInfo> balanceApplyList = new ArrayList<>();
            BalanceResponseParam.BalanceApplyInfo applyInfo = new BalanceResponseParam.BalanceApplyInfo();
            applyInfo.setApplyId(1L);
            applyInfo.setUserId(1L);
            applyInfo.setApplyMoney(new BigDecimal("1000.00"));
            applyInfo.setApplyStatus(10);
            applyInfo.setApplyType(10);
            applyInfo.setApplyDesc("打款申请描述");
            applyInfo.setApplyRemark("申请备注");
            applyInfo.setAuditStatus(10);
            applyInfo.setAuditRemark("");
            applyInfo.setBankName("中国银行");
            applyInfo.setBankAccount("1234567890123456");
            applyInfo.setAccountName("张三");
            applyInfo.setImages(new ArrayList<>());
            applyInfo.setCreateTime(LocalDateTime.now());
            balanceApplyList.add(applyInfo);
            
            responseParam.setBalanceApplyList(balanceApplyList);
            responseParam.setTotal(1L);
            responseParam.setCurrentPage(page != null ? page : 1);
            responseParam.setPerPage(listRows != null ? listRows : 10);
            responseParam.setLastPage(1);
            
        } catch (Exception e) {
            throw new CommonException("获取打款单列表失败：" + e.getMessage());
        }
        
        return responseParam;
    }

    @Override
    public BalanceResponseParam getBalanceApplyDetail(Long applyId, String token) {
        BalanceResponseParam responseParam = new BalanceResponseParam();
        
        try {
            if (applyId == null) {
                throw new CommonException("申请ID不能为空");
            }
            if (token == null || token.isEmpty()) {
                throw new CommonException("用户令牌不能为空");
            }
            
            // TODO: 获取打款单详情
            // 这里需要注入BalanceApplyMapper并查询数据库
            
            // 模拟打款单详情
            BalanceResponseParam.BalanceApplyInfo applyDetail = new BalanceResponseParam.BalanceApplyInfo();
            applyDetail.setApplyId(applyId);
            applyDetail.setUserId(1L);
            applyDetail.setApplyMoney(new BigDecimal("1000.00"));
            applyDetail.setApplyStatus(10);
            applyDetail.setApplyType(10);
            applyDetail.setApplyDesc("打款申请详情描述");
            applyDetail.setApplyRemark("申请详情备注");
            applyDetail.setAuditStatus(10);
            applyDetail.setAuditRemark("");
            applyDetail.setBankName("中国银行");
            applyDetail.setBankAccount("1234567890123456");
            applyDetail.setAccountName("张三");
            applyDetail.setImages(new ArrayList<>());
            applyDetail.setCreateTime(LocalDateTime.now());
            
            responseParam.setBalanceApplyDetail(applyDetail);
            
        } catch (Exception e) {
            throw new CommonException("获取打款单详情失败：" + e.getMessage());
        }
        
        return responseParam;
    }

    @Override
    public void cancelBalanceApply(Long applyId, String token) {
        try {
            if (applyId == null) {
                throw new CommonException("申请ID不能为空");
            }
            if (token == null || token.isEmpty()) {
                throw new CommonException("用户令牌不能为空");
            }
            
            // TODO: 取消打款单
            // 这里需要实现取消打款单逻辑，包括：
            // 1. 检查申请状态
            // 2. 更新申请状态为已取消
            // 3. 退还余额（如果已扣除）
            
            // 模拟取消打款单
            System.out.println("取消打款单：" + applyId);
            
        } catch (Exception e) {
            throw new CommonException("取消打款单失败：" + e.getMessage());
        }
    }

    @Override
    public BalanceResponseParam rechargeBalance(BalanceRequestParam requestParam) {
        BalanceResponseParam responseParam = new BalanceResponseParam();
        
        try {
            if (requestParam.getToken() == null || requestParam.getToken().isEmpty()) {
                throw new CommonException("用户令牌不能为空");
            }
            if (requestParam.getRechargeMoney() == null || requestParam.getRechargeMoney().compareTo(BigDecimal.ZERO) <= 0) {
                throw new CommonException("充值金额不能为空或小于等于0");
            }
            
            // TODO: 余额充值
            // 这里需要实现余额充值逻辑，包括：
            // 1. 调用支付接口
            // 2. 更新用户余额
            // 3. 记录充值日志
            
            // 模拟充值结果
            responseParam.setBalance(new BigDecimal("1100.00"));
            responseParam.setBalanceAll(new BigDecimal("1100.00"));
            
        } catch (Exception e) {
            throw new CommonException("余额充值失败：" + e.getMessage());
        }
        
        return responseParam;
    }

    @Override
    public UserBalanceApply submitBalanceApply(Long userId, BigDecimal money, String images) {
        try {
            if (userId == null) {
                throw new CommonException("用户ID不能为空");
            }
            if (money == null || money.compareTo(BigDecimal.ZERO) <= 0) {
                throw new CommonException("充值金额不能为空或小于等于0");
            }
            if (images == null || images.isEmpty()) {
                throw new CommonException("请上传打款凭证");
            }

            // 获取用户当前余额信息
            User user = balanceMapper.getUserBalanceDetail(userId);
            if (user == null) {
                throw new CommonException("用户信息不存在");
            }

            // 创建充值申请记录
            UserBalanceApply balanceApply = new UserBalanceApply();
            balanceApply.setUserId(userId);
            balanceApply.setMoney(money);
            balanceApply.setBeforeBalance(user.getBalance());
            balanceApply.setBeforeRebate(user.getRebate());
            balanceApply.setBeforeWriteoff(user.getWriteoff());
            balanceApply.setBalanceType(10); // 需后台审核
//            balanceApply.setBalanceTime(System.currentTimeMillis() / 1000);
            balanceApply.setBalanceStatus(10); // 待审核
            balanceApply.setImages(images);
            balanceApply.setWxappId(10001L); // 默认小程序ID
//            balanceApply.setCreateTime(System.currentTimeMillis() / 1000);
//            balanceApply.setUpdateTime(System.currentTimeMillis() / 1000);

            // 保存充值申请记录
            int result = balanceApplyMapper.insertBalanceApply(balanceApply);
            if (result <= 0) {
                throw new CommonException("保存充值申请失败");
            }

            return balanceApply;
        } catch (Exception e) {
            throw new CommonException("提交充值申请失败：" + e.getMessage());
        }
    }

    @Override
    public Page<UserBalanceApply> getUserBalanceApplyList(Long userId, Page<UserBalanceApply> page) {
        try {
            if (userId == null) {
                throw new CommonException("用户ID不能为空");
            }
            if (page == null) {
                page = new Page<>(1, 15);
            }

            Page<UserBalanceApply> balanceApplyPage = balanceApplyMapper.getBalanceApplyList(userId, page);
            return balanceApplyPage;
        } catch (Exception e) {
            throw new CommonException("获取充值申请列表失败：" + e.getMessage());
        }
    }

    @Override
    public UserBalanceApply getBalanceApplyDetailById(Long applyId, Long userId) {
        try {
            if (applyId == null) {
                throw new CommonException("申请ID不能为空");
            }
            if (userId == null) {
                throw new CommonException("用户ID不能为空");
            }

            UserBalanceApply balanceApply = balanceApplyMapper.getBalanceApplyDetail(applyId, userId);
            if (balanceApply == null) {
                throw new CommonException("充值申请记录不存在");
            }

            return balanceApply;
        } catch (Exception e) {
            throw new CommonException("获取充值申请详情失败：" + e.getMessage());
        }
    }

    @Override
    public boolean auditBalanceApply(Long applyId, Integer balanceStatus, String rejectReason, Long salesmanStoreUserId) {
        try {
            if (applyId == null) {
                throw new CommonException("申请ID不能为空");
            }
            if (balanceStatus == null) {
                throw new CommonException("审核状态不能为空");
            }
            if (balanceStatus == 30 && (rejectReason == null || rejectReason.isEmpty())) {
                throw new CommonException("驳回时必须填写驳回原因");
            }

            // 获取充值申请记录
            UserBalanceApply balanceApply = balanceApplyMapper.selectById(applyId);
            if (balanceApply == null) {
                throw new CommonException("充值申请记录不存在");
            }

            // 更新审核状态
            Long auditTime = System.currentTimeMillis() / 1000;
            int result = balanceApplyMapper.updateBalanceApplyStatus(applyId, balanceStatus, auditTime, rejectReason, salesmanStoreUserId);
            if (result <= 0) {
                throw new CommonException("更新审核状态失败");
            }

            // 如果审核通过，增加用户余额
            if (balanceStatus == 20) {
                // 增加用户余额
                int updateResult = balanceMapper.updateUserBalance(balanceApply.getUserId(), balanceApply.getMoney());
                if (updateResult <= 0) {
                    throw new CommonException("更新用户余额失败");
                }

                // 新增余额变动记录
                UserBalanceLog balanceLog = new UserBalanceLog();
                balanceLog.setUserId(balanceApply.getUserId());
                balanceLog.setScene(30); // 管理员操作
                balanceLog.setMoney(balanceApply.getMoney());
                balanceLog.setDescription("充值申请审核通过");
                balanceLog.setRemark("充值申请ID：" + applyId);
                balanceLog.setWxappId(balanceApply.getWxappId());
                balanceLog.setCreateTime(System.currentTimeMillis() / 1000);

                int logResult = balanceMapper.insertBalanceLog(balanceLog);
                if (logResult <= 0) {
                    throw new CommonException("记录余额变动日志失败");
                }
            }

            return true;
        } catch (Exception e) {
            throw new CommonException("审核充值申请失败：" + e.getMessage());
        }
    }

    @Override
    public Page<BalanceVo> getBalanceLogList(BalanceBo param, Page page) {
        Page<BalanceVo> responseVo = new Page<>();
        BizAssertUtil.notNull(param.getType(), 10001, "类型不能为空");
        
        try {
            // 根据类型选择不同的查询方式
            Page resultPage = chooseFormData(param, page);
            if (resultPage != null) {
                responseVo = (Page<BalanceVo>) resultPage;
            }
        } catch (Exception e) {
            throw new CommonException("查询余额记录失败：" + e.getMessage());
        }
        
        return responseVo;
    }

    private Page chooseFormData(BalanceBo param, Page page) {
        switch (param.getType()) {
            case 10:
                // 基本账户余额记录
                return balanceFromDate(param, page);
            case 20:
                // 返利账户余额记录 - 需要实现返利账户查询逻辑
                return getRebateBalanceLogList(param, page);
            case 30:
                // 核销账户余额记录 - 需要实现核销账户查询逻辑
                return getWriteoffBalanceLogList(param, page);
            default:
                // 默认查询基本账户余额记录
                return balanceFromDate(param, page);
        }
    }

    private Page balanceFromDate(BalanceBo param, Page page) {
        LambdaQueryWrapper<UserBalanceLog> queryWrapper = new LambdaQueryWrapper<>();
        
        // 场景筛选
        if (!Objects.isNull(param.getScene())) {
            queryWrapper.eq(UserBalanceLog::getScene, param.getScene());
        }
        
        // 时间范围筛选
        if (!Objects.isNull(param.getStartTime())) {
            queryWrapper.ge(UserBalanceLog::getCreateTime, TimeUtil.localDateToTimestampStartOfDay(param.getStartTime()));
        }
        if (!Objects.isNull(param.getEndTime())) {
            queryWrapper.le(UserBalanceLog::getCreateTime, TimeUtil.localDateToTimestampEndOfDay(param.getEndTime()));
        }
        
        // 昵称筛选：如果昵称不为空，先查询用户表获取用户ID列表
        if (ObjectUtil.isNotNull(param.getNickName()) && StrUtil.isNotBlank(param.getNickName())) {
            List<Long> userIds = getUserIdsByNickName(param.getNickName());
            if (!userIds.isEmpty()) {
                queryWrapper.in(UserBalanceLog::getUserId, userIds);
            } else {
                // 如果没有找到匹配的用户，返回空结果
                return new Page<>();
            }
        }
        
        // 排序
        queryWrapper.orderByDesc(UserBalanceLog::getCreateTime);
        
        // 分页查询
        Page<UserBalanceLog> logPage = this.page(page, queryWrapper);
        
        // 转换为BalanceVo
        Page<BalanceVo> resultPage = new Page<>();
        BeanUtils.copyProperties(logPage, resultPage);
        
        List<BalanceVo> voList = logPage.getRecords().stream()
            .map(this::convertToBalanceVo)
            .collect(Collectors.toList());
        
        resultPage.setRecords(voList);
        return resultPage;
    }
    
    /**
     * 根据昵称模糊查询用户ID列表
     * @param nickName 昵称
     * @return 用户ID列表
     */
    private List<Long> getUserIdsByNickName(String nickName) {
        LambdaQueryWrapper<User> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.like(User::getNickName, nickName)
                       .or()
                       .like(User::getRealName, nickName);
        
        List<User> users = userService.list(userQueryWrapper);
        return users.stream()
                   .map(User::getUserId)
                   .collect(Collectors.toList());
    }
    
    /**
     * 转换为BalanceVo
     */
    private BalanceVo convertToBalanceVo(UserBalanceLog log) {
        BalanceVo vo = new BalanceVo();
        BeanUtils.copyProperties(log, vo);
        
        // 设置用户信息
        if (log.getUserId() != null) {
            User user = userService.getById(log.getUserId());
            if (user != null) {
                vo.setName(user.getNickName() != null ? user.getNickName() : user.getRealName());
                vo.setUserName(user.getUserId().intValue());
            }
        }
        vo.setId(log.getLogId());
        // 设置场景文本
        vo.setSceneText(log.getSceneText());
        vo.setCreateTime(TimeUtil.changeToLocalDateTime(log.getCreateTime()));
        return vo;
    }
    
    /**
     * 查询返利账户余额记录
     */
    private Page<BalanceVo> getRebateBalanceLogList(BalanceBo param, Page page) {
        LambdaQueryWrapper<UserRebateLog> queryWrapper = new LambdaQueryWrapper<>();
        
        // 场景筛选
        if (!Objects.isNull(param.getScene())) {
            queryWrapper.eq(UserRebateLog::getScene, param.getScene());
        }
        
        // 时间范围筛选
        if (!Objects.isNull(param.getStartTime())) {
            queryWrapper.ge(UserRebateLog::getCreateTime, TimeUtil.localDateToTimestampStartOfDay(param.getStartTime()));
        }
        if (!Objects.isNull(param.getEndTime())) {
            queryWrapper.le(UserRebateLog::getCreateTime, TimeUtil.localDateToTimestampEndOfDay(param.getEndTime()));
        }
        
        // 昵称筛选：如果昵称不为空，先查询用户表获取用户ID列表
        if (ObjectUtil.isNotNull(param.getNickName()) && StrUtil.isNotBlank(param.getNickName())) {
            List<Long> userIds = getUserIdsByNickName(param.getNickName());
            if (!userIds.isEmpty()) {
                queryWrapper.in(UserRebateLog::getUserId, userIds);
            } else {
                // 如果没有找到匹配的用户，返回空结果
                return new Page<>();
            }
        }
        
        // 排序
        queryWrapper.orderByDesc(UserRebateLog::getCreateTime);
        
        // 分页查询
        Page<UserRebateLog> logPage = userRebateLogMapper.selectPage(page, queryWrapper);
        
        // 转换为BalanceVo
        Page<BalanceVo> resultPage = new Page<>();
        BeanUtils.copyProperties(logPage, resultPage);
        
        List<BalanceVo> voList = logPage.getRecords().stream()
            .map(this::convertRebateLogToBalanceVo)
            .collect(Collectors.toList());
        
        resultPage.setRecords(voList);
        return resultPage;
    }
    
    /**
     * 查询核销账户余额记录
     */
    private Page<BalanceVo> getWriteoffBalanceLogList(BalanceBo param, Page page) {
        LambdaQueryWrapper<UserWriteoffLog> queryWrapper = new LambdaQueryWrapper<>();
        
        // 场景筛选
        if (!Objects.isNull(param.getScene())) {
            queryWrapper.eq(UserWriteoffLog::getScene, param.getScene());
        }
        
        // 时间范围筛选
        if (!Objects.isNull(param.getStartTime())) {
            queryWrapper.ge(UserWriteoffLog::getCreateTime, TimeUtil.localDateToTimestampStartOfDay(param.getStartTime()));
        }
        if (!Objects.isNull(param.getEndTime())) {
            queryWrapper.le(UserWriteoffLog::getCreateTime, TimeUtil.localDateToTimestampEndOfDay(param.getEndTime()));
        }
        
        // 昵称筛选：如果昵称不为空，先查询用户表获取用户ID列表
        if (ObjectUtil.isNotNull(param.getNickName()) && StrUtil.isNotBlank(param.getNickName())) {
            List<Long> userIds = getUserIdsByNickName(param.getNickName());
            if (!userIds.isEmpty()) {
                queryWrapper.in(UserWriteoffLog::getUserId, userIds);
            } else {
                // 如果没有找到匹配的用户，返回空结果
                return new Page<>();
            }
        }
        
        // 排序
        queryWrapper.orderByDesc(UserWriteoffLog::getCreateTime);
        
        // 分页查询
        Page<UserWriteoffLog> logPage = userWriteoffLogMapper.selectPage(page, queryWrapper);
        
        // 转换为BalanceVo
        Page<BalanceVo> resultPage = new Page<>();
        BeanUtils.copyProperties(logPage, resultPage);
        
        List<BalanceVo> voList = logPage.getRecords().stream()
            .map(this::convertWriteoffLogToBalanceVo)
            .collect(Collectors.toList());
        
        resultPage.setRecords(voList);
        return resultPage;
    }
    
    /**
     * 转换返利日志为BalanceVo
     */
    private BalanceVo convertRebateLogToBalanceVo(UserRebateLog log) {
        BalanceVo vo = new BalanceVo();
        BeanUtils.copyProperties(log, vo);
        
        // 设置用户信息
        if (log.getUserId() != null) {
            User user = userService.getById(log.getUserId());
            if (user != null) {
                vo.setName(user.getNickName() != null ? user.getNickName() : user.getRealName());
                vo.setUserName(user.getUserId().intValue());
            }
        }
        vo.setId(log.getRebateId());
        // 设置场景文本
        vo.setSceneText(log.getSceneText());
        vo.setCreateTime(TimeUtil.changeToLocalDateTime(log.getCreateTime()));
        return vo;
    }
    
    /**
     * 转换核销日志为BalanceVo
     */
    private BalanceVo convertWriteoffLogToBalanceVo(UserWriteoffLog log) {
        BalanceVo vo = new BalanceVo();
        BeanUtils.copyProperties(log, vo);
        
        // 设置用户信息
        if (log.getUserId() != null) {
            User user = userService.getById(log.getUserId());
            if (user != null) {
                vo.setName(user.getNickName() != null ? user.getNickName() : user.getRealName());
                vo.setUserName(user.getUserId().intValue());
            }
        }
        vo.setId(log.getWriteoffId());
        // 设置场景文本
        vo.setSceneText(log.getSceneText());
        vo.setCreateTime(TimeUtil.changeToLocalDateTime(log.getCreateTime()));
        return vo;
    }

    @Override
    public Page<BalanceApplyListVo> getStoreBalanceApplyPage(BalanceApplyListParam param, Page<BalanceApplyListVo> page) {
        Page<UserBalanceApply> applyPage = new Page<>(page.getCurrent(), page.getSize());
        
        LambdaQueryWrapper<UserBalanceApply> queryWrapper = new LambdaQueryWrapper<>();
        
        // 审核状态筛选
        if (param.getBalanceStatus() != null) {
            queryWrapper.eq(UserBalanceApply::getBalanceStatus, param.getBalanceStatus());
        }
        
        // 时间范围筛选
//        if (StrUtil.isNotBlank(param.getStartTime())) {
//            queryWrapper.ge(UserBalanceApply::getCreateTime, TimeUtil.localDateToTimestampStartOfDay(param.getStartTime()));
//        }
//        if (StrUtil.isNotBlank(param.getEndTime())) {
//            queryWrapper.le(UserBalanceApply::getCreateTime, TimeUtil.localDateToTimestampEndOfDay(param.getEndTime()));
//        }
        
        // 用户昵称筛选
        if (StrUtil.isNotBlank(param.getNickName())) {
            List<Long> userIds = getUserIdsByNickName(param.getNickName());
            if (!userIds.isEmpty()) {
                queryWrapper.in(UserBalanceApply::getUserId, userIds);
            } else {
                // 如果没有找到匹配的用户，返回空结果
                return new Page<>();
            }
        }
        
        // 排序
        queryWrapper.orderByDesc(UserBalanceApply::getCreateTime);
        
        // 分页查询
        Page<UserBalanceApply> resultPage = balanceApplyMapper.selectPage(applyPage, queryWrapper);
        
        // 转换为VO
        Page<BalanceApplyListVo> voPage = new Page<>();
        BeanUtils.copyProperties(resultPage, voPage);
        
        List<BalanceApplyListVo> voList = resultPage.getRecords().stream()
            .map(this::convertToBalanceApplyListVo)
            .collect(Collectors.toList());
        
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public Page<RechargeReviewListVo> getRechargeReviewPage(com.huashi.dealer.modular.business.balance.param.RechargeReviewListParam param, Page<RechargeReviewListVo> page) {
        Page<UserRechargeReview> rrPage = new Page<>(page.getCurrent(), page.getSize());
        LambdaQueryWrapper<UserRechargeReview> qw = new LambdaQueryWrapper<>();
        // 状态映射
        if (param.getStatus() != null && param.getStatus() > 0) {
            Integer s = param.getStatus();
            if (s == 10 || s == 20) {
                // 初审
                if (s == 10) {
                    qw.eq(UserRechargeReview::getInitialReviewStatus, 0);
                } else {
                    qw.eq(UserRechargeReview::getInitialReviewStatus, 20);
                }
            } else if (s == 30 || s == 40 || s == 50) {
                // 复核相关：30待复核、40已驳回、50已充值
                qw.eq(UserRechargeReview::getInitialReviewStatus, 10);
                if (s == 30) {
                    qw.eq(UserRechargeReview::getCheckStatus, 0);
                } else if (s == 40) {
                    qw.eq(UserRechargeReview::getCheckStatus, 20);
                } else {
                    qw.eq(UserRechargeReview::getCheckStatus, 10);
                }
            }
        }
        // 昵称筛选
        if (StrUtil.isNotBlank(param.getNickName())) {
            List<Long> userIds = getUserIdsByNickName(param.getNickName());
            if (!userIds.isEmpty()) {
                qw.in(UserRechargeReview::getUserId, userIds);
            } else {
                return new Page<>();
            }
        }
        qw.orderByDesc(UserRechargeReview::getCreateTime);
        Page<UserRechargeReview> res = userRechargeReviewMapper.selectPage(rrPage, qw);
        Page<RechargeReviewListVo> voPage = new Page<>();
        BeanUtils.copyProperties(res, voPage);
        List<RechargeReviewListVo> voList = res.getRecords().stream().map(r -> {
            RechargeReviewListVo vo = new RechargeReviewListVo();
            BeanUtils.copyProperties(r, vo);
            if(r.getInitialReviewId() != null && r.getInitialReviewId() != 0) {
                vo.setInitialReviewName(storeUserMapper.selectById(r.getInitialReviewId()).getUserName());
            }
            if (r.getCheckId() != null && r.getCheckId() != 0) {
                vo.setCheckName(storeUserMapper.selectById(r.getCheckId()).getUserName());
            }
            vo.setInitialReviewTime(TimeUtil.changeToLocalDateTime(r.getInitialReviewTime()));
            vo.setCheckTime(TimeUtil.changeToLocalDateTime(r.getCheckTime()));
            vo.setApplyTime(TimeUtil.changeToLocalDateTime(r.getCreateTime()));
            if (r.getUserId() != null) {
                // 使用自定义Mapper方法查询，包括软删除的用户
                User u = userMapper.selectUserIncludeDeleted(r.getUserId());
                if (u != null) {
                    vo.setNickName(StrUtil.isNotBlank(u.getNickName()) ? u.getNickName() : u.getRealName());
                }
            }
            return vo;
        }).collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public void rechargeInitialReview(com.huashi.dealer.modular.business.balance.param.RechargeReviewAuditParam param, Long storeUserId) {
        BizAssertUtil.notNull(param.getRechargeReviewId(), 10001, "记录ID不能为空");
        BizAssertUtil.notNull(param.getInitialReviewStatus(), 10002, "初审状态不能为空");
        UserRechargeReview row = getRechargeReviewById(param.getRechargeReviewId());
        if (row.getInitialReviewStatus() != null && row.getInitialReviewStatus() != 0) {
            throw new ServiceException("已初审，不能重复操作");
        }
        UserRechargeReview upd = new UserRechargeReview();
        upd.setRechargeReviewId(row.getRechargeReviewId());
        upd.setInitialReviewStatus(param.getInitialReviewStatus());
        upd.setInitialReviewRejectReason(param.getInitialReviewRejectReason());
        upd.setInitialReviewId(storeUserId);
        upd.setInitialReviewTime(System.currentTimeMillis() / 1000);
        upd.setUpdateTime(System.currentTimeMillis() / 1000);
        userRechargeReviewMapper.updateById(upd);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void rechargeCheckReview(RechargeReviewAuditParam param, Long storeUserId) {
        BizAssertUtil.notNull(param.getRechargeReviewId(), 10001, "记录ID不能为空");
        BizAssertUtil.notNull(param.getCheckStatus(), 10002, "复核状态不能为空");
        UserRechargeReview row = getRechargeReviewById(param.getRechargeReviewId());
        if (row.getInitialReviewStatus() == null || row.getInitialReviewStatus() != 10) {
            throw new ServiceException("未通过初审，不能复核");
        }
        if (row.getCheckStatus() != null && row.getCheckStatus() != 0) {
            throw new ServiceException("已复核，不能重复操作");
        }
        UserRechargeReview upd = new UserRechargeReview();
        upd.setRechargeReviewId(row.getRechargeReviewId());
        upd.setCheckStatus(param.getCheckStatus());
        upd.setCheckRejectReason(param.getCheckRejectReason());
        upd.setCheckId(storeUserId);
        upd.setCheckTime(System.currentTimeMillis() / 1000);
        upd.setUpdateTime(System.currentTimeMillis() / 1000);
        // 更新记录
        userRechargeReviewMapper.updateById(upd);

        // 复核通过：执行充值
        if (param.getCheckStatus() == 10) {
            User user = userService.getById(row.getUserId());
            StoreUser storeUser = storeUserMapper.selectById(row.getStoreUserId());
            if (user == null) throw new ServiceException("用户不存在");
            switch (row.getSource()) {
                case 0: // 基本账户
                    BigDecimal amount = row.getPrice();
                    if(row.getMode().equals("dec")){
                        user.setBalance(user.getBalance().subtract(row.getPrice()));
                        amount = amount.negate();
                    }else{
                        user.setBalance(user.getBalance().add(row.getPrice()));
                    }
                    userService.updateById(user);
                    // 记录基本账户余额日志
                    UserBalanceLog log = new UserBalanceLog();
                    log.setUserId(user.getUserId());
                    log.setScene(10);
                    log.setMoney(amount);
                    log.setDescription(storeUser.getUserName()+"充值审核通过");
                    log.setRemark("充值审核ID：" + row.getRechargeReviewId());
                    log.setCreateTime(System.currentTimeMillis() / 1000);
                    balanceMapper.insert(log);
                    break;
                case 1: // 返利账户
                    BigDecimal amount1 = row.getPrice();
                    if(row.getMode().equals("dec")){
                        user.setRebate(user.getRebate().subtract(row.getPrice()));
                        amount1 = amount1.negate();
                    }else{
                        user.setRebate(user.getRebate().add(row.getPrice()));
                    }
                    userService.updateById(user);
                    UserRebateLog rlog = new UserRebateLog();
                    rlog.setUserId(user.getUserId());
                    rlog.setScene(10);
                    rlog.setMoney(amount1);
                    rlog.setDescription("后台["+storeUser.getUserName()+"]申请");
                    rlog.setRemark("充值审核-返利账户：" + row.getRechargeReviewId());
                    rlog.setCreateTime(System.currentTimeMillis() / 1000);
                    userRebateLogMapper.insert(rlog);
                    break;
                case 2: // 核销账户
                    BigDecimal amount2 = row.getPrice();
                    if(row.getMode().equals("dec")){
                        user.setWriteoff(user.getWriteoff().subtract(row.getPrice()));
                        amount2 = amount2.negate();
                    }else{
                        user.setWriteoff(user.getWriteoff().add(row.getPrice()));
                    }
                    userService.updateById(user);
                    UserWriteoffLog wlog = new UserWriteoffLog();
                    wlog.setUserId(user.getUserId());
                    wlog.setScene(10);
                    wlog.setMoney(amount2);
                    wlog.setRemark("充值审核-核销账户：" + row.getRechargeReviewId());
                    wlog.setDescription("后台["+storeUser.getUserName()+"]申请");
                    wlog.setCreateTime(System.currentTimeMillis() / 1000);
                    userWriteoffLogMapper.insert(wlog);
                    break;
                default:
                    throw new ServiceException("未知账户类型");
            }
        }
    }

    private UserRechargeReview getRechargeReviewById(Long id) {
        UserRechargeReview row = userRechargeReviewMapper.selectOne(new LambdaQueryWrapper<UserRechargeReview>()
                .eq(UserRechargeReview::getRechargeReviewId, id));
        if (row == null) throw new ServiceException("记录不存在");
        return row;
    }

    @Override
    public void storeAuditBalanceApply(Long applyId, Integer balanceStatus, String rejectReason, Long salesmanStoreUserId) {
        // 验证申请是否存在
        UserBalanceApply balanceApply = balanceApplyMapper.selectById(applyId);
        if (balanceApply == null) {
            throw new ServiceException("打款单申请不存在");
        }
        
        // 验证状态
        if (balanceApply.getBalanceStatus() != 10) {
            throw new ServiceException("该申请已审核，不能重复审核");
        }
        
        // 验证驳回原因
        if (balanceStatus == 30 && StrUtil.isBlank(rejectReason)) {
            throw new ServiceException("驳回时必须填写驳回原因");
        }
        
        // 更新申请状态
        balanceApply.setBalanceStatus(balanceStatus);
        balanceApply.setRejectReason(rejectReason);
        balanceApply.setAuditTime(System.currentTimeMillis() / 1000);
        balanceApply.setSalesmanStoreUserId(salesmanStoreUserId);
        
        balanceApplyMapper.updateById(balanceApply);
    }

    @Override
    public void storeReviewBalanceApply(Long applyId, Integer balanceStatus, String rejectReason, Long salesmanStoreUserId) {
        // 验证申请是否存在
        UserBalanceApply balanceApply = balanceApplyMapper.selectById(applyId);
        if (balanceApply == null) {
            throw new ServiceException("打款单申请不存在");
        }
        
        // 验证状态
        if (balanceApply.getBalanceStatus() != 20) {
            throw new ServiceException("该申请未通过初审，不能进行复核");
        }
        
        // 验证驳回原因
        if (balanceStatus == 30 && StrUtil.isBlank(rejectReason)) {
            throw new ServiceException("驳回时必须填写驳回原因");
        }
        
        // 更新申请状态
        balanceApply.setBalanceStatus(balanceStatus);
        balanceApply.setRejectReason(rejectReason);
        balanceApply.setAuditTime(System.currentTimeMillis() / 1000);
        balanceApply.setSalesmanStoreUserId(salesmanStoreUserId);
        
        // 如果复核通过，更新用户余额并创建余额日志
        if (balanceStatus == 40) {
            User user = userService.getById(balanceApply.getUserId());
            if (user == null) {
                throw new ServiceException("用户不存在");
            }
            
            // 更新用户余额
            user.setBalance(user.getBalance().add(balanceApply.getMoney()));
            userService.updateById(user);
            
            // 创建余额日志
            UserBalanceLog balanceLog = new UserBalanceLog();
            balanceLog.setUserId(balanceApply.getUserId().longValue());
            balanceLog.setScene(10); // 管理员充值
            balanceLog.setMoney(balanceApply.getMoney());
            balanceLog.setRemark("打款单充值：" + balanceApply.getBalanceApplyId());
            balanceLog.setDescription("用户自主充值");
            balanceLog.setCreateTime(System.currentTimeMillis() / 1000);
            balanceMapper.insert(balanceLog);
        }
        
        balanceApplyMapper.updateById(balanceApply);
    }

    /**
     * 转换打款单申请为列表VO
     */
    private BalanceApplyListVo convertToBalanceApplyListVo(UserBalanceApply apply) {
        BalanceApplyListVo vo = new BalanceApplyListVo();
        BeanUtils.copyProperties(apply, vo);
        
        // 设置用户信息
        if (apply.getUserId() != null) {
            User user = userService.getById(apply.getUserId());
            if (user != null) {
                vo.setNickName(user.getNickName() != null ? user.getNickName() : user.getRealName());
            }
        }
        
        // 设置状态文本
        switch (apply.getBalanceStatus()) {
            case 10:
                vo.setBalanceStatusText("待审核");
                break;
            case 20:
                vo.setBalanceStatusText("审核通过");
                break;
            case 30:
                vo.setBalanceStatusText("驳回");
                break;
            case 40:
                vo.setBalanceStatusText("已打款");
                break;
            default:
                vo.setBalanceStatusText("未知状态");
        }
        
        // 设置时间
        if (apply.getBalanceTime() != null) {
            vo.setBalanceTime(TimeUtil.changeToLocalDateTime(apply.getBalanceTime()));
        }
        if (apply.getAuditTime() != null) {
            vo.setAuditTime(TimeUtil.changeToLocalDateTime(apply.getAuditTime()));
        }
        
        // 设置图片列表
        if (StrUtil.isNotBlank(apply.getImages())) {
            try {
                // 解析JSON格式的图片字符串
                vo.setImages(JSON.parseArray(apply.getImages(), String.class));
            } catch (Exception e) {
                // 解析失败时设置为空列表
                vo.setImages(new ArrayList<>());
            }
        } else {
            vo.setImages(new ArrayList<>());
        }
        
        return vo;
    }
} 